using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public abstract class MainCityRealityEntity : MainCityBaseEntity
    {
        private Transform _holder;

        /// <summary>
        /// 对象池的GameObject实体
        /// </summary>
        protected Entity _objectEntity;
        protected TransformAgent _transform;
        protected AnimatorAgent _animator;

        public override TransformAgent transform => _transform;
        /// <summary>
        /// 避障代理id，动态阻挡时有效
        /// </summary>
        public uint ObstacleId { protected set; get; }
        /// <summary>
        /// 是否是Recast寻路代理（动态避障）
        /// </summary>
        protected abstract bool isRecastAgent { get; }
        /// <summary>
        /// 是否可见/激活
        /// </summary>
        public abstract bool isActive { get; }
        /// <summary>
        /// 实体加载路径
        /// </summary>
        /// <returns></returns>
        protected abstract string GetEntityLoadPath();
        /// <summary>
        /// 创建实体的TransformAgent
        /// </summary>
        /// <param name="transform"></param>
        protected abstract void CreateTransformAgent();

        public virtual async UniTask LoadAndInstantiate(Transform holder)
        {
            InitModelBase(holder);
            await ReLoadModel();
            BroadcastComponentEvent(TComponentEvent.OnEntityObjectLoaded);
        }

        /// <summary>
        /// 初始化模型的基础依赖
        /// </summary>
        /// <param name="holder"></param>
        public void InitModelBase(Transform holder)
        {
            _holder = holder;
            CreateTransformAgent();
            _animator = ClassPool<EventAnimator>.Get();
        }

        private async UniTask<Transform> LoadEntity()
        {
            if (_objectEntity != null)
            {
                LogGame.LogError("实体模型已加载，重复加载");
                return _objectEntity.gameObject.transform;
            }
            var entityResPath = GetEntityLoadPath();
            _objectEntity = ManagerCenter.Entity.Get(entityResPath, (int)EntityPoolGroupType.MainCityEntity);
            await _objectEntity.Load();
            if (_objectEntity.gameObject == null)
            {
                return null;
            }
#if UNITY_EDITOR
            _objectEntity.gameObject.name = $"[{id}]{System.IO.Path.GetFileNameWithoutExtension(entityResPath)}";
#endif
            var trans = _objectEntity.gameObject.transform;
            trans.SetParent(_holder);
            var entityDriver = trans.GetComponent<EntityDriver>();
            if (entityDriver != null)
            {
                entityDriver.defaultAudioSheet = "Character_MainCharacter";
            }
            return trans;
        }

        private void RefreshPositionAndDir()
        {
            _transform.localRotation = Quaternion.Euler(dynEntity.dirEuler.x, dynEntity.dirEuler.y, dynEntity.dirEuler.z);
            Vector3 pos = unityPosOfData;
            if (GameScenePlayUtil.TryGroundRaycast(pos.x, pos.y, pos.z, out var hit))
            {
                pos = new Vector3(pos.x, hit.point.y, pos.z);
            }
            _transform.position = pos;
        }

        /// <summary>
        /// 离开玩家视野后的逻辑
        /// </summary>
        public override void OnOutofPlayersView()
        {
            if (TryHideEntity())
            {
                _transform.Value = null;
                _animator.animator = null;
                BroadcastComponentEvent(TComponentEvent.OnEntityObjectInvisible);
            }
        }

        /// <summary>
        /// 进入玩家视野后的逻辑
        /// </summary>
        public override void OnEnterPlayersView()
        {
            LoadOnEnterPlayersView().Forget();
        }

        private async UniTask LoadOnEnterPlayersView()
        {
            if (!isActive)
            {
                return;
            }
            await ReLoadModel();
            base.OnEnterPlayersView();
            BroadcastComponentEvent(TComponentEvent.OnEntityObjectVisible);
        }

        protected async UniTask ReLoadModel()
        {
            var trans = await LoadEntity();
            _transform.Value = trans;
            _animator.animator = GetUnityAnimator();
            RefreshPositionAndDir();
        }

        protected bool TryHideEntity()
        {
            if (_objectEntity != null)
            {
                _transform.DOKill();
                ManagerCenter.Entity.HideEntity(_objectEntity);
                _objectEntity = null;
                BroadcastComponentEvent(TComponentEvent.OnEntityObjectHided);
                return true;
            }
            return false;
        }

        public override void UpdatePosToData(Vector3 position)
        {
            this.dynEntity.UpdatePos(position);
        }

        public override AnimatorAgent GetAnimator()
        {
            return _animator;
        }

        private Animator GetUnityAnimator()
        {
            var modelTransform = _transform.Find("model");
            if (modelTransform == null)
            {
                modelTransform = _transform;
            }
            var anim = modelTransform?.GetComponent<Animator>();
            if (anim == null) //不是真的null
            {
                return null;
            }
            return anim;
        }

        /// <summary>
        /// 在寻路网格中传送
        /// </summary>
        /// <param name="useAgentMove"></param>
        /// <param name="targetPoint"></param>
        /// <returns></returns>
        protected virtual bool TeleportInNavMesh(bool useAgentMove, Vector3 targetPoint)
        {
            bool success = false;
            int errorCode = 1;
            if (navigationCtrl.FindNearestPoint(targetPoint, out var validRealPos))
            {
                errorCode = 2;
                if (useAgentMove)
                {
                    if (navigationCtrl.SetAgentPos(ObstacleId, validRealPos))
                    {
                        success = true;
                        errorCode = 0;
                    }
                }
                else
                {
                    success = true;
                    errorCode = 0;
                }
            }

            if (success)
            {
                SetPosition(validRealPos);
            }
            else
            {
                LogGame.LogError($"传送失败，目标点：{targetPoint}，{(errorCode == 1 ? "目标点附近没有找到可行走区域" : (errorCode == 2 ? "移动阻挡Agent失败" : "Unknown"))}");
            }
            return success;
        }

        public void Teleport(Vector3 position)
        {
            TeleportInNavMesh(isRecastAgent, position);
        }

        /// <summary>
        /// 设置位置
        /// 同时刷新dynEntity的数据和unity transform的位置
        /// </summary>
        /// <param name="position"></param>
        public override void SetPosition(Vector3 position)
        {
            base.SetPosition(position);
            transform.position = position;
        }

        public override void Free()
        {
            TryHideEntity();
            base.Free();
        }

        public override void OnReset()
        {
            base.OnReset();
            _holder = null;
            if (_transform != null)
            {
                ClassPool.PutAutoType(_transform);
                _transform = null;
            }
            if (_animator != null)
            {
                ClassPool.PutAutoType(_animator);
                _animator = null;
            }
            ObstacleId = 0;
        }
    }
}
